package com.xs.micro.tool.service;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.xs.micro.tool.domain.pojo.em.QueryEnterpriseInfoType;
import com.xs.micro.tool.domain.pojo.vo.EnterpriseInfoResultVO;
import com.xs.micro.tool.domain.pojo.vo.QueryEnterpriseInfoParamVO;
import okhttp3.OkHttpClient;
import okhttp3.Request;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public abstract class BaseQueryDataService {

    public abstract QueryEnterpriseInfoType type();

    public abstract List<EnterpriseInfoResultVO> query(QueryEnterpriseInfoParamVO queryParam) throws Exception;

    /**
     * 对输入的字符串进行URL编码, 即转换为%20这种形式
     *
     * @param input 原文
     * @return URL编码. 如果编码失败, 则返回原文
     */
    public String encode(String input) {
        if (input == null) {
            return "";
        }
        try {
            return URLEncoder.encode(input, StandardCharsets.UTF_8.name());
        } catch (Exception e) {

        }

        return input;
    }

    protected WebClient createWebClient() {
        WebClient webClient = new WebClient(BrowserVersion.CHROME);
        //当JS执行出错的时候是否抛出异常, 这里选择不需要
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        //当HTTP的状态非200时是否抛出异常, 这里选择不需要
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.getOptions().setActiveXNative(true);
        //是否启用CSS, 因为不需要展现页面, 所以不需要启用
        webClient.getOptions().setCssEnabled(true);
        //很重要，启用JS
        webClient.getOptions().setJavaScriptEnabled(true);
        //很重要，设置支持AJAX
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        //设置“浏览器”的请求超时时间
        webClient.getOptions().setTimeout(30000);
        // 重定向
        webClient.getOptions().setRedirectEnabled(true);
        webClient.getOptions().setUseInsecureSSL(true);
        // 开启cookies
        webClient.getCookieManager().setCookiesEnabled(true);
        //设置JS执行的超时时间
        webClient.setJavaScriptTimeout(30000);
        return webClient;
    }

    protected OkHttpClient createOkHttpClient(Map<String, String> header) {
        return new OkHttpClient.Builder()
                // 连接超时(单位:秒)
                .connectTimeout(30, TimeUnit.SECONDS)
                // 写入超时(单位:秒)
                .writeTimeout(30, TimeUnit.SECONDS)
                // 读取超时(单位:秒)
                .readTimeout(30, TimeUnit.SECONDS)
                .addInterceptor(chain -> {
                    Request original = chain.request();
                    Request.Builder builder = original.newBuilder();
                    for (Map.Entry<String, String> entry : header.entrySet()) {
                        builder.addHeader(entry.getKey(), entry.getValue());
                    }
                    Request request = builder
                            .method(original.method(), original.body())
                            .build();
                    return chain.proceed(request);
                })
                .build();
    }

}
